package com.zwq.service.impl;

import com.zwq.exception.BusinessException;
import com.zwq.pojo.dto.UserDto;
import com.zwq.pojo.entity.User;
import com.zwq.pojo.request.user.UserEmailLoginRequest;
import com.zwq.pojo.request.user.UserPasswordLoginRequest;
import com.zwq.pojo.request.user.UserRegisterRequest;
import com.zwq.repository.UserRepository;
import com.zwq.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String fromEmail;

    @Value("${wechat.mp.app-id}")
    public String appId;

    @Value("${wechat.mp.secret}")
    public String appSecret;

    @Value("${wechat.mp.redirect-uri}")
    public String redirectUri;

    // 存储邮箱验证码和微信登录ticket的临时缓存
    private final Map<String, String> emailCodeCache = new ConcurrentHashMap<>();
    private final Map<String, String> wechatTicketCache = new ConcurrentHashMap<>();

    @Override
    public UserDto loginByPassword(String username, String password) {
        User user = userRepository.findByUsername(username)
                .orElse(null);
        if (user == null || !passwordEncoder.matches(password, user.getPassword())) {
            throw new BusinessException("用户名或密码错误");
        }
        return UserDto.convertBy(user);
    }

    @Override
    public UserDto loginByEmail(String email, String code) {
        String cachedCode = emailCodeCache.get(email);
        if (cachedCode == null || !cachedCode.equals(code)) {
            throw new BusinessException("验证码错误或已过期");
        }
        User user = userRepository.findByEmail(email).orElse(null);
        if (user == null) {
            user = new User();
            user.setEmail(email);
            user.setRole("FARMER"); // 默认角色
            userRepository.save(user);
        }
        emailCodeCache.remove(email);
        return UserDto.convertBy(user);
    }

    @Override
    public Map<String, String> getWechatQr() {
        String url = "https://open.weixin.qq.com/connect/qrconnect" +
                "?appid=%s" +
                "&redirect_uri=%s" +
                "&response_type=code" +
                "&scope=snsapi_login" +  // 固定值
                "&state=YOUR_STATE";     // 防CSRF攻击随机字符串（需存储校验）
        HashMap<String, String> map = new HashMap<>();
        map.put("url", String.format(url, appId, URLEncoder.encode(redirectUri, StandardCharsets.UTF_8)));
        return map;
    }

    @Override
    public UserDto checkWechatLogin(String code, String state) {
        return null;
    }

    @Override
    public void sendEmailCode(String email) {
        String code = String.format("%06d", new Random().nextInt(999999));
        emailCodeCache.put(email, code);

        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(fromEmail);
        message.setTo(email);
        message.setSubject("智慧农业系统 - 验证码");
        message.setText("欢迎登录/注册智慧农业系统，您的验证码是：" + code + "，有效期5分钟。");
        mailSender.send(message);
    }

    // 模拟微信扫码回调（实际需通过微信API实现）
    public void simulateWechatScan(String ticket, String openId) {
        wechatTicketCache.put(ticket, openId);
    }

    @Override
    public UserDto register(UserRegisterRequest request) {
        if (userRepository.findByUsername(request.getUsername()).isPresent()) {
            throw new BusinessException("用户名已存在");
        }
        if (userRepository.findByEmail(request.getEmail()).isPresent()) {
            throw new BusinessException("邮箱已注册");
        }

        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(passwordEncoder.encode(request.getPassword())); // 加密密码
        user.setRealName(request.getRealName());
        user.setEmail(request.getEmail());
        user.setRole(request.getRole()); // 从请求中获取角色，而不是默认 "FARMER"

        // 根据角色处理农业相关字段
        if ("FARMER".equals(request.getRole())) {
            if (request.getAgriculturalField() == null || request.getAgriculturalField().isEmpty()) {
                throw new BusinessException("农民必须选择农业领域");
            }
            user.setAgriculturalField(request.getAgriculturalField());

            if (request.getAgriculturalMachines() == null || request.getAgriculturalMachines().isEmpty()) {
                throw new BusinessException("农业机器数据格式错误");
            }
            user.setAgriculturalMachines(request.getAgriculturalMachines());

        } else if ("MANAGER".equals(request.getRole())) {
            user.setAgriculturalField(null);
            user.setAgriculturalMachines(null);
        } else {
            throw new BusinessException("无效的用户角色");
        }

        userRepository.save(user);
        return UserDto.convertBy(user);
    }

    // 获取个人信息（假设通过当前登录用户）
    @Override
    public UserDto getProfile(Long userId) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        return UserDto.convertBy(user);
    }

    // 更新个人信息
    @Override
    public UserDto updateProperty(Long userId, UserDto userDto) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));

        // 更新字段
        user.setUsername(userDto.getUsername());
        user.setRealName(userDto.getRealName());
        user.setEmail(userDto.getEmail());
        // role 不允许修改
        if ("FARMER".equals(user.getRole())) {
            if (userDto.getAgriculturalField() == null || userDto.getAgriculturalField().isEmpty()) {
                throw new BusinessException("农民必须选择农业领域");
            }
            user.setAgriculturalField(userDto.getAgriculturalField());
            if (userDto.getAgriculturalMachines() == null || userDto.getAgriculturalMachines().isEmpty()) {
                throw new BusinessException("农业机器数据格式错误");
            }
            user.setAgriculturalMachines(userDto.getAgriculturalMachines());
        } else if ("MANAGER".equals(user.getRole())) {
            user.setAgriculturalField(null);
            user.setAgriculturalMachines(null);
        }

        userRepository.save(user);
        return UserDto.convertBy(user);
    }

}